package com.lincoln.tb.spider.util;

import com.alibaba.fastjson.JSONArray;
import com.lincoln.tb.spider.Pic;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Utils {
    private static Logger logger = LoggerFactory.getLogger(Utils.class);

    /**
     * 判断url是否是淘宝链接
     *
     * @param url
     * @return
     */
    public static boolean isTb(String url) {
        if (url.startsWith("https://item.taobao.com") || url.startsWith("item.taobao.com")) {
            return true;
        }
        return false;
    }

    /**
     * 判断url是否是天猫链接
     *
     * @param url
     * @return
     */
    public static boolean isTm(String url) {
        if (url.startsWith("https://detail.tmall.com") || url.startsWith("detail.tmall.com")) {
            return true;
        }
        return false;
    }

    public static List<Pic> spiderTbPic(String url) {
        List<Pic> res = new ArrayList<>();
        Document document = null;
        try {
            document = Jsoup.connect(url).get();
            String goodName = document.title();
            goodName = goodName.replaceAll("/", "-");
            Elements elements = document.getElementsByTag("script");
            if (elements != null && elements.size() > 0) {
                String script = elements.get(0).html();
                int i = script.indexOf("auctionImages    :") + "auctionImages    :".length();
                script = script.substring(i, script.indexOf("}", i));
                JSONArray jsonArray = JSONArray.parseArray(script);

                for (int j = 0; j < jsonArray.size(); j++) {
                    String u = (String) jsonArray.get(j);
                    res.add(new Pic(goodName + (j == 0 ? "" : ("-" + j)), (u.startsWith("http") ? "" : "http:") + u));
                }
                return res;
            } else {
                return res;
            }
        } catch (IOException e) {
            logger.error("{}", e);
            return res;
        }
    }

    /**
     * 爬取天猫的主图
     *
     * @param url
     * @return
     */
    public static List<Pic> spiderTmPic(String url) {
        List<Pic> res = new ArrayList<>();
        Document document = null;
        try {
            document = Jsoup.connect(url).get();
            String goodName = document.title();
            goodName = goodName.replaceAll("/", "-");
            Element ul = document.getElementById("J_UlThumb");
            if (ul != null) {
                Elements elements = ul.getElementsByTag("li");
                if (elements == null || elements.size() <= 0) {
                    return res;
                }
                int i = 0;
                for (Element element : elements) {
                    Elements imgs = element.getElementsByTag("img");
                    if (imgs != null && imgs.size() > 0) {
                        String imgUrl = "http:" + imgs.get(0).attr("src");
                        if (imgUrl.substring(0, imgUrl.lastIndexOf(".jpg")).lastIndexOf(".jpg") != -1) {
                            imgUrl = imgUrl.substring(0, imgUrl.lastIndexOf(".jpg"));
                            imgUrl = imgUrl.substring(0, imgUrl.lastIndexOf("_"));
                        }
                        res.add(new Pic(goodName + (i == 0 ? "" : ("-" + i)), imgUrl));
                        i++;
                    }
                }
                return res;
            } else {
                return res;
            }
        } catch (IOException e) {
            logger.error("{}", e);
            return res;
        }
    }

    public static byte[] spiderPic(String[] urls, boolean onlyOne) {
        List<Pic> task = new ArrayList<>();
        for (String url : urls) {
            if (isTb(url)) {
                List<Pic> picUrls = spiderTbPic(url);
                if (onlyOne) {
                    if (picUrls.size() > 0) {
                        task.add(picUrls.get(0));
                    }
                } else {
                    task.addAll(picUrls);
                }
            } else if (isTm(url)) {
                List<Pic> picUrls = spiderTmPic(url);
                if (onlyOne) {
                    if (picUrls.size() > 0) {
                        task.add(picUrls.get(0));
                    }
                } else {
                    task.addAll(picUrls);
                }
            } else {

            }
        }
        Map<String, Pic> picMap = new HashMap<>(task.size());
        for (Pic pic : task) {
            picMap.put(pic.getUrl(), pic);
        }
        for (Pic pic : picMap.values()) {
            byte[] content = downloadPic(pic.getUrl());
            pic.setContent(content);
        }
        return packageZip(picMap.values());
    }

    public static byte[] downloadPic(String url) {
        Connection.Response response = null;
        try {
            response = Jsoup.connect(url).ignoreContentType(true).execute();
        } catch (Exception e) {
            logger.error("{}", e);
            return null;
        }
        byte[] img = response.bodyAsBytes();
        return img;
    }

    public static byte[] packageZip(Collection<Pic> task) {
        ZipOutputStream zipStream = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        zipStream = new ZipOutputStream(bos);
        BufferedInputStream bufferStream = null;
        byte[] bs = null;
        List<byte[]> bytelist = new ArrayList<byte[]>();
        for (Pic pic : task) {
            if (pic.getContent() == null) {
                continue;
            }
            try {
                ZipEntry zipEntry = new ZipEntry(pic.getFileName() + ".jpg");
                zipStream.putNextEntry(zipEntry);
                bufferStream = new BufferedInputStream(new ByteArrayInputStream(pic.getContent()));
                int read = 0;
                byte[] bufferArea = new byte[1024 * 10];
                while ((read = bufferStream.read(bufferArea, 0, 1024 * 10)) != -1) {
                    zipStream.write(bufferArea, 0, read);
                }
            } catch (Exception e) {
                logger.error("{}", e);
            }
        }
        try {
            zipStream.closeEntry();
            zipStream.close();
        } catch (IOException e) {
            logger.error("{}", e);
        }
        bs = bos.toByteArray();
        try {
            bos.close();
        } catch (IOException e) {
            logger.error("{}", e);
        }
        bytelist.add(bs);
        bs = bytesCombine(bytelist);
        logger.info("成功打包了" + bytelist.size() + "张图片");
        return bs;
    }

    /**
     * byte数组的合并
     *
     * @param srcArrays
     * @return
     */
    private static byte[] bytesCombine(List<byte[]> srcArrays) {
        byte[] destArrays = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            for (byte[] srcArray : srcArrays) {
                bos.write(srcArray);
            }
            destArrays = bos.toByteArray();
            bos.flush();
        } catch (IOException e) {
            logger.error("{}", e);
        } finally {
            try {
                bos.close();
            } catch (IOException e) {
            }
        }
        return destArrays;
    }

    public static void main(String[] args) {
        spiderTbPic("https://item.taobao.com/item.htm?spm=a21bo.7929913.198967.15.7f3641742GtZZy&id=525350133736");
    }
}
